#include "stdafx.h"
#include "LoadShader.h"

#include "Renderer.h"

using namespace mgfx;

typedef std::map<std::string, ShaderID> ResourceMap;
static ResourceMap mResources;

ShaderID mgfx::loadShaderFromFile(const std::string & fileName)
{
	return loadShaderFromFile(fileName, std::vector<ShaderDefine>());
}

ShaderID mgfx::loadShaderFromFile(const std::string & fileName, const ShaderDefine & define)
{
	std::vector<ShaderDefine> singleDefine(1);
	singleDefine.push_back(define);
	return loadShaderFromFile(fileName, singleDefine);
}

ShaderID mgfx::loadShaderFromFile( const std::string & fileName, const ShaderDefine & define, const ShaderDefine & define2 )
{
	std::vector<ShaderDefine> defines(2);
	defines.push_back(define);
	defines.push_back(define2);
	return loadShaderFromFile(fileName, defines);
}

ShaderID mgfx::loadShaderFromFile(const std::string & fileName, const std::vector<ShaderDefine> & defines)
{
	std::string hash = fileName;

	ShaderMacro macros[64];
	for(uint i = 0; i < defines.size(); i++)
	{
		hash += defines[i].Name;
		hash += defines[i].Definition;

		ShaderMacro macro = { defines[i].Name.c_str(), defines[i].Definition.c_str() };
		macros[i] = macro;
	}

	ResourceMap::const_iterator found = mResources.find(hash);
	if(found != mResources.end())
	{
		return found->second;
	}
	else
	{
		ShaderID shader;
		if(defines.size() > 0)
		{
			std::string path = "content\\fx\\";
			path += fileName;
			shader = Renderer::Instance->addShader(path.c_str(), macros, defines.size());
		}
		else
		{
			std::string path = "shaders_build\\";
			path += fileName;
			path += "o"; // .fxo instead of .fx
			shader = Renderer::Instance->addShaderFromBinaryFile(path.c_str());
		}

		mResources[hash] = shader;
  
		return shader;
	}
}
